package Parser;
/*
 * XMLTree.java
 *
 * Created on February 24, 2009, 1:05 AM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

import java.io.BufferedReader;
import java.util.ArrayList;

public class XMLTree {
    XMLToken[] tokens;
    
    /** Creates a new instance of XMLTree */
    public XMLTree(BufferedReader read) throws Exception {
        createTree(read);
    }
    
    public XMLToken[] getTree() {
        return tokens;
    }
    
    public StringBuffer getAllText(int start, int stop)
    {
        StringBuffer text = new StringBuffer();
        XMLToken tag;

        for (int c = start; c < stop; c++)
        {
            tag = tokens[c];
            if (tag.isText())
            {
                text.append(tag.toString());
                text.append(' ');
            }
        }

        return text;
    }
    
    public int findClose(int token)
    {
        int counter;
        XMLToken start = tokens[token];
        XMLToken tag;

        counter = token + 1;
        while (counter < tokens.length)
        {
            tag = tokens[counter];
            if (tag.closes(start))
              return counter;
            else if (tag.getName().equals(start.getName()))
            {
              try {
                counter = findClose(counter) + 1;
              }
              catch (HTMLException e)
              {
                throw new HTMLException("Malformed xml - Tag is not closed:  " + start.toString());
              }
            }
            else
              counter++;
        }

        throw new HTMLException("Malformed xml - Tag is not closed:  " + start.toString());
    }
    
    public int findNextTag(int start, String type)
    {
        int c;

        for (c = start; c < tokens.length; c++)
        {
            if (tokens[c].getName().equals(type))
              return c;
        }

        return -1;
    }
    
    public int findPreviousTag(int start, String type)
    {
        int c;

        for (c = start; c >= 0; c--)
        {
            if (tokens[c].getName().equals(type))
              return c;
        }

        return -1;
    }
    
    public void createTree(BufferedReader read) throws Exception {
        char cur;
        int in = 0;
        int count = 0;
        StringBuffer token;
        ArrayList<XMLToken> list = new ArrayList<XMLToken>();
        
        // Read the whole thing
        in = read.read();
        cur = (char) in;
        while (in >= 0) {
            token = new StringBuffer("");
            if (cur == '<') {
                while (cur != '>' && in >= 0) {
                    token.append(cur);
                    in = read.read();
                    cur = (char) in;
                }
                token.append(cur);
                in = read.read();
                cur = (char) in;
            } else {
                while (cur != '<' && in >= 0) {
                    token.append(cur);
                    in = read.read();
                    cur = (char) in;
                }
            }
            
            list.add(new XMLToken(token.toString()));
            count++;
            if (count % 500 == 0) {
                System.gc();
            }
        }
        
        tokens = new XMLToken[list.size()];
        for (int c = 0; c < tokens.length; c++) {
            tokens[c] = list.get(c);
        }
    }
    
}
